{% if access_list is vyos_defined %}
{%     for acl, acl_config in access_list.items() | natural_sort %}
{%         if acl_config.description is vyos_defined %}
access-list {{ acl }} remark {{ acl_config.description }}
{%         endif %}
{%         if acl_config.rule is vyos_defined %}
{%             for rule, rule_config in acl_config.rule.items() | natural_sort %}
{%                 set ip = '' %}
{%                 set src = '' %}
{%                 set src_mask = '' %}
{%                 if rule_config.source.any is vyos_defined %}
{%                     set src = 'any' %}
{%                 elif rule_config.source.host is vyos_defined %}
{%                     set src = 'host ' ~ rule_config.source.host %}
{%                 elif rule_config.source.network is vyos_defined %}
{%                     set src = rule_config.source.network %}
{%                     set src_mask = rule_config.source.inverse_mask %}
{%                 endif %}
{%                 set dst = '' %}
{%                 set dst_mask = '' %}
{%                 if (acl | int >= 100 and acl | int <= 199) or (acl | int >= 2000 and acl | int <= 2699) %}
{%                     set ip = 'ip' %}
{%                     set dst = 'any' %}
{%                     if rule_config.destination.any is vyos_defined %}
{%                         set dst = 'any' %}
{%                     elif rule_config.destination.host is vyos_defined %}
{%                         set dst = 'host ' ~ rule_config.destination.host %}
{%                     elif rule_config.destination.network is vyos_defined %}
{%                         set dst = rule_config.destination.network %}
{%                         set dst_mask = rule_config.destination.inverse_mask %}
{%                     endif %}
{%                 endif %}
access-list {{ acl }} seq {{ rule }} {{ rule_config.action }} {{ ip }} {{ src }} {{ src_mask }} {{ dst }} {{ dst_mask }}
{%             endfor %}
{%         endif %}
{%     endfor %}
{% endif %}
!
{% if access_list6 is vyos_defined %}
{%     for acl, acl_config in access_list6.items() | natural_sort %}
{%         if acl_config.description is vyos_defined %}
ipv6 access-list {{ acl }} remark {{ acl_config.description }}
{%         endif %}
{%         if acl_config.rule is vyos_defined %}
{%             for rule, rule_config in acl_config.rule.items() | natural_sort %}
{%                 set src = '' %}
{%                 if rule_config.source.any is vyos_defined %}
{%                     set src = 'any' %}
{%                 elif rule_config.source.network is vyos_defined %}
{%                     set src = rule_config.source.network %}
{%                 endif %}
ipv6 access-list {{ acl }} seq {{ rule }} {{ rule_config.action }} {{ src }} {{ 'exact-match' if rule_config.source.exact_match is vyos_defined }}
{%             endfor %}
{%         endif %}
{%     endfor %}
{% endif %}
!
{% if as_path_list is vyos_defined %}
{%     for acl, acl_config in as_path_list.items() | natural_sort %}
{%         if acl_config.rule is vyos_defined %}
{%             for rule, rule_config in acl_config.rule.items() | natural_sort %}
bgp as-path access-list {{ acl }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }}
{%             endfor %}
{%         endif %}
{%     endfor %}
{% endif %}
!
{% if community_list is vyos_defined %}
{%     for list, list_config in community_list.items() | natural_sort %}
{%         if list_config.rule is vyos_defined %}
{%             for rule, rule_config in list_config.rule.items() | natural_sort %}
{#                 by default, if casting to int fails it returns 0 #}
{%                 if list | int != 0 %}
bgp community-list {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }}
{%                 else %}
bgp community-list expanded {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }}
{%                 endif %}
{%             endfor %}
{%         endif %}
{%     endfor %}
{% endif %}
!
{% if extcommunity_list is vyos_defined %}
{%     for list, list_config in extcommunity_list.items() | natural_sort %}
{%         if list_config.rule is vyos_defined %}
{%             for rule, rule_config in list_config.rule.items() | natural_sort %}
{#                 by default, if casting to int fails it returns 0 #}
{%                 if list | int != 0 %}
bgp extcommunity-list {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }}
{%                 else %}
bgp extcommunity-list expanded {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }}
{%                 endif %}
{%             endfor %}
{%         endif %}
{%     endfor %}
{% endif %}
!
{% if large_community_list is vyos_defined %}
{%     for list, list_config in large_community_list.items() | natural_sort %}
{%         if list_config.rule is vyos_defined %}
{%             for rule, rule_config in list_config.rule.items() | natural_sort %}
{#                 by default, if casting to int fails it returns 0 #}
{%                 if list | int != 0 %}
bgp large-community-list {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }}
{%                 else %}
bgp large-community-list expanded {{ list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.regex }}
{%                 endif %}
{%             endfor %}
{%         endif %}
{%     endfor %}
{% endif %}
!
{% if prefix_list is vyos_defined %}
{%     for prefix_list, prefix_list_config in prefix_list.items() | natural_sort %}
{%         if prefix_list_config.description is vyos_defined %}
ip prefix-list {{ prefix_list }} description {{ prefix_list_config.description }}
{%         endif %}
{%         if prefix_list_config.rule is vyos_defined %}
{%             for rule, rule_config in prefix_list_config.rule.items() | natural_sort %}
{%                 if rule_config.prefix is vyos_defined %}
ip prefix-list {{ prefix_list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.prefix }} {{ 'ge ' ~ rule_config.ge if rule_config.ge is vyos_defined }} {{ 'le ' ~ rule_config.le if rule_config.le is vyos_defined }}
{%                 endif %}
{%             endfor %}
{%         endif %}
{%     endfor %}
{% endif %}
!
{% if prefix_list6 is vyos_defined %}
{%     for prefix_list, prefix_list_config in prefix_list6.items() | natural_sort %}
{%         if prefix_list_config.description is vyos_defined %}
ipv6 prefix-list {{ prefix_list }} description {{ prefix_list_config.description }}
{%         endif %}
{%         if prefix_list_config.rule is vyos_defined %}
{%             for rule, rule_config in prefix_list_config.rule.items() | natural_sort %}
{%                 if rule_config.prefix is vyos_defined %}
ipv6 prefix-list {{ prefix_list }} seq {{ rule }} {{ rule_config.action }} {{ rule_config.prefix }} {{ 'ge ' ~ rule_config.ge if rule_config.ge is vyos_defined }} {{ 'le ' ~ rule_config.le if rule_config.le is vyos_defined }}
{%                 endif %}
{%             endfor %}
{%         endif %}
{%     endfor %}
{% endif %}
!
{% if route_map is vyos_defined %}
{%     for route_map, route_map_config in route_map.items() | natural_sort %}
{%         if route_map_config.rule is vyos_defined %}
{%             for rule, rule_config in route_map_config.rule.items() | natural_sort %}
route-map {{ route_map }} {{ rule_config.action }} {{ rule }}
{%                 if rule_config.call is vyos_defined %}
 call {{ rule_config.call }}
{%                 endif %}
{%                 if rule_config.continue is vyos_defined %}
 on-match goto {{ rule_config.continue }}
{%                 endif %}
{%                 if rule_config.description is vyos_defined %}
 description {{ rule_config.description }}
{%                 endif %}
{%                 if rule_config.match is vyos_defined %}
{%                     if rule_config.match.as_path is vyos_defined %}
 match as-path {{ rule_config.match.as_path }}
{%                     endif %}
{%                     if rule_config.match.community.community_list is vyos_defined %}
 match community {{ rule_config.match.community.community_list }} {{ 'exact-match' if rule_config.match.community.exact_match is vyos_defined }}
{%                     endif %}
{%                     if rule_config.match.extcommunity is vyos_defined %}
 match extcommunity {{ rule_config.match.extcommunity }}
{%                     endif %}
{%                     if rule_config.match.evpn.default_route is vyos_defined %}
 match evpn default-route
{%                     endif %}
{%                     if rule_config.match.evpn.rd is vyos_defined %}
 match evpn rd {{ rule_config.match.evpn.rd }}
{%                     endif %}
{%                     if rule_config.match.evpn.route_type is vyos_defined %}
 match evpn route-type {{ rule_config.match.evpn.route_type }}
{%                     endif %}
{%                     if rule_config.match.evpn.vni is vyos_defined %}
 match evpn vni {{ rule_config.match.evpn.vni }}
{%                     endif %}
{%                     if rule_config.match.interface is vyos_defined %}
 match interface {{ rule_config.match.interface }}
{%                     endif %}
{%                     if rule_config.match.ip.address.access_list is vyos_defined %}
 match ip address {{ rule_config.match.ip.address.access_list }}
{%                     endif %}
{%                     if rule_config.match.ip.address.prefix_list is vyos_defined %}
 match ip address prefix-list {{ rule_config.match.ip.address.prefix_list }}
{%                     endif %}
{%                     if rule_config.match.ip.address.prefix_len is vyos_defined %}
 match ip address prefix-len {{ rule_config.match.ip.address.prefix_len }}
{%                     endif %}
{%                     if rule_config.match.ip.nexthop.access_list is vyos_defined %}
 match ip next-hop {{ rule_config.match.ip.nexthop.access_list }}
{%                     endif %}
{%                     if rule_config.match.ip.nexthop.address is vyos_defined %}
 match ip next-hop address {{ rule_config.match.ip.nexthop.address }}
{%                     endif %}
{%                     if rule_config.match.ip.nexthop.prefix_len is vyos_defined %}
 match ip next-hop prefix-len {{ rule_config.match.ip.nexthop.prefix_len }}
{%                     endif %}
{%                     if rule_config.match.ip.nexthop.prefix_list is vyos_defined %}
 match ip next-hop prefix-list {{ rule_config.match.ip.nexthop.prefix_list }}
{%                     endif %}
{%                     if rule_config.match.ip.nexthop.type is vyos_defined %}
 match ip next-hop type {{ rule_config.match.ip.nexthop.type }}
{%                     endif %}
{%                     if rule_config.match.ip.route_source.access_list is vyos_defined %}
 match ip route-source {{ rule_config.match.ip.route_source.access_list }}
{%                     endif %}
{%                     if rule_config.match.ip.route_source.prefix_list is vyos_defined %}
 match ip route-source prefix-list {{ rule_config.match.ip.route_source.prefix_list }}
{%                     endif %}
{%                     if rule_config.match.ipv6.address.access_list is vyos_defined %}
 match ipv6 address {{ rule_config.match.ipv6.address.access_list }}
{%                     endif %}
{%                     if rule_config.match.ipv6.address.prefix_list is vyos_defined %}
 match ipv6 address prefix-list {{ rule_config.match.ipv6.address.prefix_list }}
{%                     endif %}
{%                     if rule_config.match.ipv6.address.prefix_len is vyos_defined %}
 match ipv6 address prefix-len {{ rule_config.match.ipv6.address.prefix_len }}
{%                     endif %}
{%                     if rule_config.match.ipv6.nexthop.address is vyos_defined %}
 match ipv6 next-hop address {{ rule_config.match.ipv6.nexthop.address }}
{%                     endif %}
{%                     if rule_config.match.ipv6.nexthop.access_list is vyos_defined %}
 match ipv6 next-hop {{ rule_config.match.ipv6.nexthop.access_list }}
{%                     endif %}
{%                     if rule_config.match.ipv6.nexthop.prefix_list is vyos_defined %}
 match ipv6 next-hop prefix-list {{ rule_config.match.ipv6.nexthop.prefix_list }}
{%                     endif %}
{%                     if rule_config.match.ipv6.nexthop.type is vyos_defined %}
 match ipv6 next-hop type {{ rule_config.match.ipv6.nexthop.type }}
{%                     endif %}
{%                     if rule_config.match.large_community.large_community_list is vyos_defined %}
 match large-community {{ rule_config.match.large_community.large_community_list }}
{%                     endif %}
{%                     if rule_config.match.local_preference is vyos_defined %}
 match local-preference {{ rule_config.match.local_preference }}
{%                     endif %}
{%                     if rule_config.match.metric is vyos_defined %}
 match metric {{ rule_config.match.metric }}
{%                     endif %}
{%                     if rule_config.match.origin is vyos_defined %}
 match origin {{ rule_config.match.origin }}
{%                     endif %}
{%                     if rule_config.match.peer is vyos_defined %}
 match peer {{ rule_config.match.peer }}
{%                     endif %}
{%                     if rule_config.match.protocol is vyos_defined %}
{%                         set source_protocol = 'ospf6' if rule_config.match.protocol == 'ospfv3' else rule_config.match.protocol %}
 match source-protocol {{ source_protocol }}
{%                     endif %}
{%                     if rule_config.match.rpki is vyos_defined %}
 match rpki {{ rule_config.match.rpki }}
{%                     endif %}
{%                     if rule_config.match.tag is vyos_defined %}
 match tag {{ rule_config.match.tag }}
{%                     endif %}
{%                 endif %}
{%                 if rule_config.on_match.next is vyos_defined %}
 on-match next
{%                 endif %}
{%                 if rule_config.on_match.goto is vyos_defined %}
 on-match goto {{ rule_config.on_match.goto }}
{%                 endif %}
{%                 if rule_config.set is vyos_defined %}
{%                     if rule_config.set.aggregator.as is vyos_defined and rule_config.set.aggregator.ip is vyos_defined %}
 set aggregator as {{ rule_config.set.aggregator.as }} {{ rule_config.set.aggregator.ip }}
{%                     endif %}
{%                     if rule_config.set.as_path.exclude is vyos_defined %}
 set as-path exclude {{ rule_config.set.as_path.exclude }}
{%                     endif %}
{%                     if rule_config.set.as_path.prepend is vyos_defined %}
 set as-path prepend {{ rule_config.set.as_path.prepend }}
{%                     endif %}
{%                     if rule_config.set.as_path.prepend_last_as is vyos_defined %}
 set as-path prepend last-as {{ rule_config.set.as_path.prepend_last_as }}
{%                     endif %}
{%                     if rule_config.set.atomic_aggregate is vyos_defined %}
 set atomic-aggregate
{%                     endif %}
{%                     if rule_config.set.community.delete is vyos_defined %}
 set comm-list {{ rule_config.set.community.delete }} delete
{%                     endif %}
{%                     if rule_config.set.community.replace is vyos_defined %}
 set community {{ rule_config.set.community.replace | join(' ') | replace("local-as" , "local-AS") }}
{%                     endif %}
{%                     if rule_config.set.community.add is vyos_defined %}
 set community {{ rule_config.set.community.add | join(' ') | replace("local-as" , "local-AS") }} additive
{%                     endif %}
{%                     if rule_config.set.community.none is vyos_defined %}
 set community none
{%                     endif %}
{%                     if rule_config.set.distance is vyos_defined %}
 set distance {{ rule_config.set.distance }}
{%                     endif %}
{%                     if rule_config.set.evpn.gateway.ipv4 is vyos_defined %}
 set evpn gateway-ip ipv4 {{ rule_config.set.evpn.gateway.ipv4 }}
{%                     endif %}
{%                     if rule_config.set.evpn.gateway.ipv6 is vyos_defined %}
 set evpn gateway-ip ipv6 {{ rule_config.set.evpn.gateway.ipv6 }}
{%                     endif %}
{%                     if rule_config.set.extcommunity.bandwidth is vyos_defined %}
 set extcommunity bandwidth {{ rule_config.set.extcommunity.bandwidth }} {{ 'non-transitive' if rule_config.set.extcommunity.bandwidth_non_transitive is vyos_defined }}
{%                     endif %}
{%                     if rule_config.set.extcommunity.rt is vyos_defined %}
 set extcommunity rt {{ rule_config.set.extcommunity.rt | join(' ') }}
{%                     endif %}
{%                     if rule_config.set.extcommunity.soo is vyos_defined %}
 set extcommunity soo {{ rule_config.set.extcommunity.soo | join(' ') }}
{%                     endif %}
{%                     if rule_config.set.extcommunity.none is vyos_defined %}
 set extcommunity none
{%                     endif %}
{%                     if rule_config.set.ip_next_hop is vyos_defined %}
 set ip next-hop {{ rule_config.set.ip_next_hop }}
{%                     endif %}
{%                     if rule_config.set.ipv6_next_hop.global is vyos_defined %}
 set ipv6 next-hop global {{ rule_config.set.ipv6_next_hop.global }}
{%                     endif %}
{%                     if rule_config.set.ipv6_next_hop.local is vyos_defined %}
 set ipv6 next-hop local {{ rule_config.set.ipv6_next_hop.local }}
{%                     endif %}
{%                     if rule_config.set.ipv6_next_hop.peer_address is vyos_defined %}
 set ipv6 next-hop peer-address
{%                     endif %}
{%                     if rule_config.set.ipv6_next_hop.prefer_global is vyos_defined %}
 set ipv6 next-hop prefer-global
{%                     endif %}
{%                     if rule_config.set.l3vpn_nexthop.encapsulation.gre is vyos_defined %}
set l3vpn next-hop encapsulation gre
{%                     endif %}
{%                     if rule_config.set.large_community.replace is vyos_defined %}
 set large-community {{ rule_config.set.large_community.replace | join(' ') }}
{%                     endif %}
{%                     if rule_config.set.large_community.add is vyos_defined %}
 set large-community {{ rule_config.set.large_community.add | join(' ') }} additive
{%                     endif %}
{%                     if rule_config.set.large_community.none is vyos_defined %}
 set large-community none
{%                     endif %}
{%                     if rule_config.set.large_community.delete is vyos_defined %}
 set large-comm-list {{ rule_config.set.large_community.delete }} delete
{%                     endif %}
{%                     if rule_config.set.local_preference is vyos_defined %}
 set local-preference {{ rule_config.set.local_preference }}
{%                     endif %}
{%                     if rule_config.set.metric is vyos_defined %}
 set metric {{ rule_config.set.metric }}
{%                     endif %}
{%                     if rule_config.set.metric_type is vyos_defined %}
 set metric-type {{ rule_config.set.metric_type }}
{%                     endif %}
{%                     if rule_config.set.origin is vyos_defined %}
 set origin {{ rule_config.set.origin }}
{%                     endif %}
{%                     if rule_config.set.originator_id is vyos_defined %}
 set originator-id {{ rule_config.set.originator_id }}
{%                     endif %}
{%                     if rule_config.set.src is vyos_defined %}
 set src {{ rule_config.set.src }}
{%                     endif %}
{%                     if rule_config.set.table is vyos_defined %}
 set table {{ rule_config.set.table }}
{%                     endif %}
{%                     if rule_config.set.tag is vyos_defined %}
 set tag {{ rule_config.set.tag }}
{%                     endif %}
{%                     if rule_config.set.weight is vyos_defined %}
 set weight {{ rule_config.set.weight }}
{%                     endif %}
{%                 endif %}
exit
!
{%             endfor %}
{%         endif %}
{%     endfor %}
{% endif %}
